#include <func.h>
#include "BlockQ.h"

#define COUNT 8

typedef struct
{
    pthread_t thread[COUNT];
    BlockQ* Q;

} pool;

void* start_routine(void* arg)
{
    pool* pl = (pool*)arg;
    while(1)
    {
        E ret = blockq_pop(pl->Q);
        if(ret == -1)
        {
            printf("0x%lu exit\n", pthread_self());
            sleep(3);
            pthread_exit(NULL);
        }
            sleep(3);
        printf("0x%lu EXE %d\n",pthread_self(), ret);
    }
    return NULL;
}

pool* create_pool(void)
{
    pool* pl = (pool*)malloc(sizeof(pool));
    pl->Q = blockq_create();
    for(int i = 0; i < COUNT; ++i)
    { 
        int err =  pthread_create(pl->thread + i, NULL, start_routine, (void*)pl);
        if(err)
            error(1, err, "pthread_create");
    }

    return pl;
}

void destory_pool(pool* pl)
{
    blockq_destroy(pl->Q);
    free(pl);
}

int main(void)
{
    // main线程
    // 1. 创建线程池
    printf("---\n");
    pool* pl = create_pool();
    // 2. 主线程往阻塞队列中放任务; 子线程从阻塞队列中取任务，然后执行任务
    printf("---\n");
    for(int i = 1; i <= 100; ++i)
        blockq_push(pl->Q, i);
    // 3. 线程池优雅地退出
    printf("---\n");
    for(int i = 1; i <= COUNT; ++i)
        blockq_push(pl->Q, -1);
    for(int i = 0; i < COUNT; ++i)
        pthread_join(*(pl->thread + i), NULL);

    // 4. 销毁线程池
    printf("---\n");
    destory_pool(pl);
    return 0;
}

